#include <QUrl>
#include <QDateTime>

#include "../global/QmlNames.h"
#include "../util/Singleton.h"
#include "AudioRecorder.h"

X_BEGIN_NAMESPACE

/**
 * @brief 录音器。
 *
 * 录音器可以设置多种参数，编码器，码率，格式，声道数，录音设备等。
 * 暂时先硬编码，之后根据需要增加参数配置。
 *
 * 配置可参见：Audio Recorder Example 示例
 */

AudioRecorder::AudioRecorder(QObject *parent)
    : QObject(parent),
      m_codec("audio/mpeg"),
      m_encodingQuality(QMultimedia::HighQuality)
{
    QAudioEncoderSettings audioSettings;
    audioSettings.setCodec(m_codec);
    audioSettings.setChannelCount(2);
    audioSettings.setQuality(m_encodingQuality);
    m_audioRecorder.setEncodingSettings(audioSettings);
}

AudioRecorder &AudioRecorder::instance()
{
    return *Singleton<AudioRecorder>::instance(AudioRecorder::createInstance);
}

const char* AudioRecorder::qmlName()
{
    return QmlNames::Utils::AudioRecorderSingleton;
}

QObject *AudioRecorder::qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine)
{
    Q_UNUSED(engine);
    Q_UNUSED(scriptEngine);

    return &instance();
}

bool AudioRecorder::recording() const
{
    QAudioRecorder::State state = m_audioRecorder.state();
    return state == QAudioRecorder::RecordingState;
}

bool AudioRecorder::paused() const
{
    QAudioRecorder::State state = m_audioRecorder.state();
    return state == QAudioRecorder::PausedState;
}

bool AudioRecorder::stopped() const
{
    QAudioRecorder::State state = m_audioRecorder.state();
    return state == QAudioRecorder::StoppedState;
}

QString AudioRecorder::fileName() const
{
    return m_fileName;
}

void AudioRecorder::start()
{
    if(recording()){
        qDebug() << "Recording, please stop it if you want start again.";
        return;
    } else if(paused()){
        m_audioRecorder.record();
        emit pausedChanged(false);
    } else {
        QString now = QDateTime::currentDateTime().toString("yyyy_MM-dd_HH_mm_ss");
        m_fileName = tr("/Users/sand/Desktop/audio_%1.wav").arg(now);

        QUrl url = QUrl::fromLocalFile(m_fileName);
        m_audioRecorder.setOutputLocation(url);
        m_audioRecorder.record();

        emit recordingChanged(true);
    }
}

void AudioRecorder::pause()
{
    if(recording()){
        m_audioRecorder.pause();

        emit pausedChanged(true);
    }
}

void AudioRecorder::stop()
{
    if(recording() || stopped()){
        m_audioRecorder.stop();

        emit recordingChanged(false);
        emit fileNameChanged(m_fileName);
        return;
    }

    qDebug() << "NOT recording now, please start it first.";
}

AudioRecorder *AudioRecorder::createInstance()
{
    return new AudioRecorder;
}

X_END_NAMESPACE
